<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title></title>

    <script src="../Scripts/jquery-1.7.2.js" type="text/javascript"></script>
    <script src="../Output/Photon-debug.js" type="text/javascript"></script>
    <script type="text/javascript">
        var Extension = function () {

        };


        photon.defineType(
                Extension,
                photon.observable.model.Extension,
                {
                    define:function (m) {
                        photon.array.forEach(photon.object.getOwnPropertyNames(m), function (propertyName) {
                            var member = m[propertyName];
                            if (member && typeof member === 'object') {
                                var calculated = member.calculated;
                                if (calculated) {
                                    var Property = photon.defineType(
                                            function Property(owner) {
                                                this.owner_ = owner;
                                                this.dependencyTracker_ = new photon.observable.DependencyTracker(this.update, this);
                                            },
                                            {
                                                update:function() {
                                                    var newValue = this.calculate();
                                                    var oldValue = this.value_;
                                                    if (oldValue != newValue) {
                                                        this.value_ = newValue;
                                                        this.owner_.notifyPropertyChanged(propertyName, oldValue, newValue);
                                                    }
                                                },
                                                calculate:function () {
                                                    photon.observable.DependencyTracker.registerDependency(this.owner_, propertyName);
                                                    this.dependencyTracker_.beginCapture();
                                                    try {
                                                        return calculated.call(this.owner_);
                                                    }
                                                    finally {
                                                        this.dependencyTracker_.endCapture();
                                                    }
                                                }
                                            });
                                    m[propertyName + "_"] = {
                                        initializer:function(owner) {
                                            return new Property(owner);
                                        }
                                    }
                                    m[propertyName] = function() {
                                        return this.propertyValues_[propertyName + "_"].calculate();
                                    }
                                    m[propertyName].isPropertyAccessor = true;

                                }

                            }
                        });
                    }
                });
        photon.observable.model.extensions.calculated = new Extension();

        var Person = function(firstName, lastName) {
            Person.base(this, {
                firstName:firstName,
                lastName:lastName
            });
        };

        photon.observable.model.define(Person,
                {
                    firstName:null,
                    lastName:null,
                    fullName:{
                        calculated : function() {
                            return this.firstName() + ' ' + this.lastName();
                        }
                    }
                });

        var Manager = function() {
            Manager.base(this, "", "");
        }

        photon.observable.model.define(Manager, Person, {
            manages:{
                type:'ObservableArray'
            }
        });

        $(function() {
            var model = new Manager();
            photon.binding.applyBindings(model);
        })
    </script>
</head>
<body>
   <input data-bind="value:firstName"><p></p>
   <input data-bind="value:lastName"><p></p>
   <input data-bind="value:fullName"><p></p>
</body>
</html>